Update standards to c++17, Qt >= 5.12, MSVC >= 2017 (#670)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Wed, 27 Jan 2021 19:01:41 +0000 (12:01 -0700)
committerGitHub <noreply@github.com>
Wed, 27 Jan 2021 19:01:41 +0000 (12:01 -0700)
* raise minimum standards to c++17, Qt 5.12, MSVC 2017.

* avoid std::optional::value which didn't work until macOS 10.14.

* avoid std::optional::value which didn't work until macOS 10.14.

* update runner for codeql so we have Qt >= 5.12

* try harder to get codeql working with newer Qt.

* use c++17 fallthrough attribute.

* use c++17 'if constexpr' as suggested by resharper.

* catch mkicondoc up with c++17

32 files changed:
.github/workflows/codeql-analysis.yml
.github/workflows/ubuntu.yml
.github/workflows/windows.yml
CMakeLists.txt
GPSBabel.pro
defs.h
delgpl.cc
dmtlog.cc
g7towin.cc
garmin_fit.cc
garmin_fit.h
gpx.h
gui/CMakeLists.txt
gui/app.pro
gui/main.cc
height.cc
igc.cc
igo8.cc
interpolate.cc
interpolate.h
kml.cc
lowranceusr.cc
lowranceusr.h
main.cc
mkicondoc/mkicondoc.pro
route.cc
skytraq.cc
src/core/deprecated/optional.h [new file with mode: 0644]
src/core/optional.h [deleted file]
util.cc
xcsv.cc
xcsv.h

index 2822167bdc7bc250304bacec920e8e49df4698b8..e71c1e0c12586b6f726806fb76c591c2538ea0ac 100644 (file)
@@ -25,7 +25,7 @@ jobs:
   analyze:
     name: Analyze
     runs-on: ubuntu-latest
-    container: tsteven4/gpsbabel_build_environment
+    container: tsteven4/gpsbabel_build_environment_focal
 
     strategy:
       fail-fast: false
index 08440e47a0c1e98e0570c428902bc1811f512052..3b2edc22d174a16e34cdc9182561850f1b041742 100644 (file)
@@ -14,7 +14,7 @@ jobs:
     name: basic Build
     runs-on: ubuntu-latest
     container:
-      image: gpsbabel-docker.jfrog.io/tsteven4/gpsbabel_build_environment
+      image: gpsbabel-docker.jfrog.io/tsteven4/gpsbabel_build_environment_focal
       env:
         LC_ALL: 'C.UTF-8'
 
index 446e62a511b12903cad32e12ca795479840dc9cd..59c59811b8bfafb980f80a1073217fd855f97e7f 100644 (file)
@@ -43,13 +43,6 @@ jobs:
             VCVERSION: '14.16'
             FLOW: 'nmake'
             RELEASE: false
-          - QT_VERSION: '5.12.10'
-            ARCH: 'amd64'
-            HOST_ARCH: 'x86'
-            COMPILER: 'msvc2017_64'
-            VCVERSION: '14.0'
-            FLOW: 'nmake'
-            RELEASE: false
           - QT_VERSION: '5.12.10'
             ARCH: 'x86'
             HOST_ARCH: 'x86'
index 3654531e244eda05fc4d515fb9723e5af467dd87..0f0b3dbfcbda0b3ba188f15fe40be2194e96dcde 100644 (file)
@@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.5.1)
 
 project(gpsbabel LANGUAGES C CXX)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # Find includes in corresponding build directories
@@ -15,7 +15,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 # Find the Qt5Core library
 find_package(Qt5 COMPONENTS Core REQUIRED)
-if(${Qt5Core_VERSION} VERSION_LESS 5.9)
+if(${Qt5Core_VERSION} VERSION_LESS 5.12)
   message(FATAL_ERROR "Qt version ${Qt5Core_VERSION} found, but version 5.9 or newer is required.")
 else()
   message(STATUS "Using Qt5 version ${Qt5Core_VERSION}")
@@ -179,7 +179,6 @@ set(HEADERS
   src/core/datetime.h
   src/core/file.h
   src/core/logging.h
-  src/core/optional.h
   src/core/textstream.h
   src/core/usasciicodec.h
   src/core/xmlstreamwriter.h
index f6ef73746a4164b16fc62834b7df5ad1a24461e6..f9ed6ecea5b61671d238727613253bc36bfd9773 100644 (file)
@@ -1,6 +1,6 @@
 # Enforce minimum Qt version.
 # versionAtLeast() was introduced in Qt 5.10, so we can't count on it being available.
-MIN_QT_VERSION = 5.9 # major[.minor[.patch]]
+MIN_QT_VERSION = 5.12 # major[.minor[.patch]]
 MIN_QT_VERSION_COMPONENTS = $$split(MIN_QT_VERSION, .)
 MIN_QT_VERSION_MAJOR = $$member(MIN_QT_VERSION_COMPONENTS, 0)
 MIN_QT_VERSION_MINOR = $$member(MIN_QT_VERSION_COMPONENTS, 1)
@@ -20,7 +20,7 @@ VERSION = 1.7.0
 
 CONFIG += console
 CONFIG -= app_bundle
-CONFIG += c++14
+CONFIG += c++17
 CONFIG += link_pkgconfig
 
 TEMPLATE = app
@@ -182,7 +182,6 @@ HEADERS =  \
        src/core/datetime.h \
        src/core/file.h \
        src/core/logging.h \
-       src/core/optional.h \
        src/core/textstream.h \
        src/core/usasciicodec.h \
        src/core/xmlstreamwriter.h \
diff --git a/defs.h b/defs.h
index e35dc2625ff979ccfe5d84e0203485703c6fbc19..a6617f0f50feb2f97946991d6ffd6cdc5f424352 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -26,6 +26,7 @@
 #include <cstdint>                // for int32_t, uint32_t
 #include <cstdio>                 // for NULL, fprintf, FILE, stdout
 #include <ctime>                  // for time_t
+#include <optional>               // for optional
 #include <utility>                // for move
 
 #if HAVE_CONFIG_H
@@ -52,7 +53,6 @@
 #include "gbfile.h"               // doesn't really belong here, but is missing elsewhere.
 #include "session.h"              // for session_t
 #include "src/core/datetime.h"    // for DateTime
-#include "src/core/optional.h"    // for optional
 
 
 #define CSTR(qstr) ((qstr).toUtf8().constData())
@@ -676,17 +676,17 @@ waypt_disp_all(T cb)
  */
 struct computed_trkdata {
   double distance_meters{0.0};
-  gpsbabel_optional::optional<double> max_alt; /* Meters */
-  gpsbabel_optional::optional<double> min_alt; /* Meters */
-  gpsbabel_optional::optional<double> max_spd; /* Meters/sec */
-  gpsbabel_optional::optional<double> min_spd; /* Meters/sec */
-  gpsbabel_optional::optional<double> avg_hrt; /* Avg Heartrate */
-  gpsbabel_optional::optional<double> avg_cad; /* Avg Cadence */
+  std::optional<double> max_alt;       /* Meters */
+  std::optional<double> min_alt;       /* Meters */
+  std::optional<double> max_spd;       /* Meters/sec */
+  std::optional<double> min_spd;       /* Meters/sec */
+  std::optional<double> avg_hrt;       /* Avg Heartrate */
+  std::optional<double> avg_cad;       /* Avg Cadence */
   gpsbabel::DateTime start;            /* Min time */
   gpsbabel::DateTime end;              /* Max time */
-  gpsbabel_optional::optional<int> min_hrt;                    /* Min Heartrate */
-  gpsbabel_optional::optional<int> max_hrt;                    /* Max Heartrate */
-  gpsbabel_optional::optional<int> max_cad;                    /* Max Cadence */
+  std::optional<int> min_hrt;                  /* Min Heartrate */
+  std::optional<int> max_hrt;                  /* Max Heartrate */
+  std::optional<int> max_cad;                  /* Max Cadence */
 };
 
 class route_head
@@ -974,20 +974,6 @@ void setshort_defname(short_handle, const char* s);
 #define ARG_NOMINMAX nullptr, nullptr
 
 struct arglist_t {
-  /* MSVC 2015 generates C2440, C2664 errors without some help. */
-#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */
-  arglist_t() = default;
-  arglist_t(const char* astr, char** aval, const char* hstr, const char* dval,
-            const uint32_t atyp, const char* minv, const char* maxv, char* avp) :
-            argstring(astr),
-            argval(aval),
-            helpstring(hstr),
-            defaultvalue(dval),
-            argtype(atyp),
-            minvalue(minv),
-            maxvalue(maxv),
-            argvalptr(avp) {}
-#endif
   const char* argstring{nullptr};
   char** argval{nullptr};
   const char* helpstring{nullptr};
index 4b911793c056d4fa429f1b1731f6ec1d1b0a1572..c368f9a9217ee08a3f9a61e71f86cc4576ea6519 100644 (file)
--- a/delgpl.cc
+++ b/delgpl.cc
@@ -42,7 +42,7 @@ static void
 gpl_rd_init(const QString& fname)
 {
   gplfile_in = gbfopen_le(fname, "rb", MYNAME);
-  if (sizeof(gpl_point_t) != 56) {
+  if constexpr (sizeof(gpl_point_t) != 56) {
     fatal(MYNAME ": gpl_point is %zu instead of 56.\n",
           sizeof(gpl_point_t));
   }
index 07fe094ae347de5aa6efda8a4ef165f42613543b..3b5597598646206f6dcd9170aeada389698ed631 100644 (file)
--- a/dmtlog.cc
+++ b/dmtlog.cc
@@ -585,7 +585,7 @@ inflate_buff(const char* buff, const size_t size, char** out_buff)
     switch (res) {
     case Z_NEED_DICT:
       res = Z_DATA_ERROR;
-      /* fallthrough */
+      [[fallthrough]];
     case Z_DATA_ERROR:
     case Z_MEM_ERROR:
       (void)inflateEnd(&strm);
index 4efcc98db073898d91f83a7ee26e8540b7e03c7b..108ebad7e533a500a089f16d6d19dfd3474861ee 100644 (file)
@@ -188,7 +188,7 @@ parse_line(char* buff, int index, const char* delimiter, Waypoint* wpt)
       if (strcmp(cin, "1.0e25") == 0) {
         break;
       }
-      /* fallthrough */
+      [[fallthrough]];
     case WPT_cD_OFS + 1:
     case WPT_cB_OFS + 6:
       WAYPT_SET(wpt, temperature, atof(cin));
index 4208fbcb02c413fed7378aef797dbd90af66a2df..29ae7d4560822560dc29cde4a1bf3b9074e7856e 100644 (file)
 
 #define MYNAME "fit"
 
-// Until c++17 we have to define odr-used constexpr static data members at namespace scope.
-#if __cplusplus < 201703L
-constexpr int GarminFitFormat::kTypeEnum;
-constexpr int GarminFitFormat::kTypeUint8;
-constexpr int GarminFitFormat::kTypeString;
-constexpr int GarminFitFormat::kTypeUint16;
-constexpr int GarminFitFormat::kTypeSint32;
-constexpr int GarminFitFormat::kTypeUint32;
-constexpr int GarminFitFormat::kCoursePointTypeLeft;
-constexpr int GarminFitFormat::kCoursePointTypeRight;
-#endif
-
 /*******************************************************************************
 * %%%        global callbacks called by gpsbabel main process              %%% *
 *******************************************************************************/
index 4cbd8d8cb25c5c9d710b767162863cab025e21cb..6fc6ab69b6da7f6395eeb8c114b6739035da5324 100644 (file)
@@ -84,11 +84,6 @@ private:
   /* Types */
 
   struct fit_field_t {
-    /* MSVC 2015 generates C2664 errors without some help. */
-#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */
-    fit_field_t() = default;
-    fit_field_t(int i, int s, int t) : id(i), size(s), type(t) {}
-#endif
     int id {};
     int size{};
     int type{};
diff --git a/gpx.h b/gpx.h
index 4b9bc1a934c8cb25bda06d6f066112d734b88f86..4247afe53d7518c4c26966e04b7a4a887ea7fffb 100644 (file)
--- a/gpx.h
+++ b/gpx.h
@@ -182,11 +182,6 @@ private:
   };
 
   struct tag_mapping {
-#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */
-    /* avoid MSVC 2015 C2664 errors. */
-    tag_mapping() = default;
-    tag_mapping(tag_type t, bool p) : type(t),passthrough(p) {}
-#endif
     tag_type type{tt_unknown};         /* enum from above for this tag */
     bool passthrough{true};            /* true if we don't generate this */
   };
index 9fd4ee063039795a06b0c02c2d23af3614fa6184..99b157e44917ccdeb6febf5ef0458be9ae00ce1f 100644 (file)
@@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.5.1)
 
 project(gpsbabelfe LANGUAGES CXX)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # Find includes in corresponding build directories
@@ -22,7 +22,7 @@ set(CMAKE_AUTORCC ON)
 # Find the Qt5Core library
 find_package(Qt5 COMPONENTS Core Gui Network Widgets Xml REQUIRED)
 list(APPEND QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Network Qt5::Widgets Qt5::Xml)
-if(${Qt5Core_VERSION} VERSION_LESS 5.9)
+if(${Qt5Core_VERSION} VERSION_LESS 5.12)
   message(FATAL_ERROR "Qt version ${Qt5Core_VERSION} found, but version 5.9 or newer is required.")
 else()
   message(STATUS "Using Qt5 version ${Qt5Core_VERSION}")
index 1e4307ddd85c4a0dd699f28ad22258be6d4dd233..4d20d0d83448a031a2b098ef9c3d4fffe0ecf32f 100755 (executable)
@@ -5,6 +5,7 @@ CONFIG += qt
 CONFIG(debug, debug|release) {
   CONFIG += console
 }
+CONFIG += c++17
 
 ICON = images/appicon.icns
 
index 3d8a2614b2663c21c170d89c550085bf8e1daebe..87a4a3fdc3e557fdb117ca575480d0d29f488f03 100644 (file)
 //------------------------------------------------------------------------
 int main(int argc, char** argv)
 {
-// MIN_QT_VERSION in configure.ac should correspond to the QT_VERSION_CHECK arguments in main.cc and gui/main.cc
-#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
+// MIN_QT_VERSION in GPSBabel.pro should correspond to the QT_VERSION_CHECK
+// arguments in main.cc and gui/main.cc and the version check in
+// CMakeLists.txt, gui/CMakeLists.txt.
+#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
 #error this version of Qt is not supported.
 #endif
 
index 8f265db02f05dcbca482f974bb2323200f6659d3..eb62846f44aa37d7df9babf49bdc08b073a58247 100644 (file)
--- a/height.cc
+++ b/height.cc
 
 #if FILTERS_ENABLED
 
-// Until c++17 we have to define odr-used constexpr static data members at namespace scope.
-#if __cplusplus < 201703L
-constexpr double HeightFilter::geoid_grid_deg;
-constexpr double HeightFilter::geoid_scale;
-constexpr int HeightFilter::geoid_row;
-constexpr int HeightFilter::geoid_col;
-constexpr int8_t HeightFilter::geoid_delta[geoid_row][geoid_col];
-#endif
-
 double HeightFilter::bilinear(double x1, double y1, double x2, double y2, double x, double y, double z11, double z12, double z21, double z22)
 {
   if (y1 == y2 && x1 == x2) {
diff --git a/igc.cc b/igc.cc
index 1375f6c479e9444957dfb335f590539a12f43818..fd860c3e48a08798a0f7d3497a42478a1022c64a 100644 (file)
--- a/igc.cc
+++ b/igc.cc
@@ -29,6 +29,7 @@
 #include <cstring>                   // for strcmp, strlen, strtok, strcat, strchr, strcpy, strncat
 #include <ctime>                     // for gmtime, ctime
 #include <iterator>                  // for reverse_iterator, operator==, prev, next
+#include <optional>                  // for optional
 
 #include <QtCore/QByteArray>         // for QByteArray
 #include <QtCore/QList>              // for QList<>::const_iterator
@@ -40,7 +41,6 @@
 #include "cet_util.h"                // for cet_convert_init
 #include "gbfile.h"                  // for gbfprintf, gbfclose, gbfopen, gbfputs, gbfgetstr, gbfile
 #include "src/core/datetime.h"       // for DateTime
-#include "src/core/optional.h"       // for optional
 
 
 static gbfile* file_in, *file_out;
@@ -815,8 +815,8 @@ static int correlate_tracks(const route_head* pres_track, const route_head* gnss
  */
 static double interpolate_alt(const route_head* track, time_t time)
 {
-  static gpsbabel_optional::optional<WaypointList::const_iterator> prev_wpt;
-  static gpsbabel_optional::optional<WaypointList::const_iterator> curr_wpt;
+  static std::optional<WaypointList::const_iterator> prev_wpt;
+  static std::optional<WaypointList::const_iterator> curr_wpt;
   int time_diff;
 
   // Start search at the beginning of the track
@@ -825,32 +825,32 @@ static double interpolate_alt(const route_head* track, time_t time)
     curr_wpt = track->waypoint_list.cbegin();
   }
   // Find the track points either side of the requested time
-  while ((track->waypoint_list.cend() != curr_wpt.value()) &&
-         ((*curr_wpt.value())->GetCreationTime().toTime_t() < time)) {
-    prev_wpt = curr_wpt.value();
-    curr_wpt = std::next(prev_wpt.value());
+  while ((track->waypoint_list.cend() != *curr_wpt) &&
+         ((**curr_wpt)->GetCreationTime().toTime_t() < time)) {
+    prev_wpt = *curr_wpt;
+    curr_wpt = std::next(*prev_wpt);
   }
-  if (track->waypoint_list.cend() == curr_wpt.value()) {
+  if (track->waypoint_list.cend() == *curr_wpt) {
     // Requested time later than all track points, we can't interpolate
     return unknown_alt;
   }
 
-  if (track->waypoint_list.cbegin() == curr_wpt.value()) {
-    if ((*curr_wpt.value())->GetCreationTime().toTime_t() == time) {
+  if (track->waypoint_list.cbegin() == *curr_wpt) {
+    if ((**curr_wpt)->GetCreationTime().toTime_t() == time) {
       // First point's creation time is an exact match so use it's altitude
-      return (*curr_wpt.value())->altitude;
+      return (**curr_wpt)->altitude;
     } else {
       // Requested time is prior to any track points, we can't interpolate
       return unknown_alt;
     }
   }
   // Interpolate
-  if (0 == (time_diff = (*curr_wpt.value())->GetCreationTime().toTime_t() - (*prev_wpt.value())->GetCreationTime().toTime_t())) {
+  if (0 == (time_diff = (**curr_wpt)->GetCreationTime().toTime_t() - (**prev_wpt)->GetCreationTime().toTime_t())) {
     // Avoid divide by zero
-    return (*curr_wpt.value())->altitude;
+    return (**curr_wpt)->altitude;
   }
-  double alt_diff = (*curr_wpt.value())->altitude - (*prev_wpt.value())->altitude;
-  return (*prev_wpt.value())->altitude + (alt_diff / time_diff) * (time - (*prev_wpt.value())->GetCreationTime().toTime_t());
+  double alt_diff = (**curr_wpt)->altitude - (**prev_wpt)->altitude;
+  return (**prev_wpt)->altitude + (alt_diff / time_diff) * (time - (**prev_wpt)->GetCreationTime().toTime_t());
 }
 
 /*
diff --git a/igo8.cc b/igo8.cc
index 111f7bd1af6f64caae6091f3904f393d88619a78..505654bf5a86b8d428b2170beeb6213185b03bde 100644 (file)
--- a/igo8.cc
+++ b/igo8.cc
@@ -128,17 +128,17 @@ static QVector<arglist_t> igo8_options = {
 // Sanity check
 static void igo8_check_type_sizes()
 {
-  if (sizeof(igo8_point) != 12) {
+  if constexpr (sizeof(igo8_point) != 12) {
     fatal(MYNAME ": igo8_point is %ld bytes instead of the required 12.\n",
           (long) sizeof(igo8_point));
   }
 
-  if (sizeof(igo8_information_block) != 12) {
+  if constexpr (sizeof(igo8_information_block) != 12) {
     fatal(MYNAME ": igo8_information_block is %ld bytes instead of the required 12.\n",
           (long) sizeof(igo8_information_block));
   }
 
-  if (sizeof(igo8_id_block) != 20) {
+  if constexpr (sizeof(igo8_id_block) != 20) {
     fatal(MYNAME ": igo8_id_block is %ld bytes instead of the required 20.\n",
           (long) sizeof(igo8_id_block));
   }
index ae1df8ed0a4fc0fe7ccf4556f3e3d53489238032..ad1232e794c3766907dfdcbdcb8af1c227d48478 100644 (file)
@@ -22,6 +22,7 @@
 #include <climits>              // for INT_MAX
 #include <cmath>                // for abs, ceil, isfinite, round
 #include <cstdlib>              // for abs, atoi, strtod
+#include <optional>             // for optional
 
 #include <QtCore/QString>       // for QString
 #include <QtCore/QtGlobal>      // for qAsConst, QAddConst<>::Type
@@ -31,7 +32,6 @@
 #include "grtcirc.h"            // for linepart, RAD, gcdist, radtomiles
 #include "src/core/datetime.h"  // for DateTime
 #include "src/core/logging.h"   // for Fatal
-#include "src/core/optional.h"  // for optional
 
 
 #if FILTERS_ENABLED
@@ -79,12 +79,12 @@ void InterpolateFilter::process()
       if (first) {
         first = false;
       } else {
-        gpsbabel_optional::optional<qint64> timespan;
+        std::optional<qint64> timespan;
         if (wpt->creation_time.isValid() && time1.isValid()) {
           timespan = wpt->creation_time.toMSecsSinceEpoch() -
                      time1.toMSecsSinceEpoch();
         }
-        gpsbabel_optional::optional<double> altspan;
+        std::optional<double> altspan;
         if (altitude1 != unknown_alt && wpt->altitude != unknown_alt) {
           altspan = wpt->altitude - altitude1;
         }
@@ -96,7 +96,7 @@ void InterpolateFilter::process()
             fatal(FatalMsg() << MYNAME ": points must have valid times to interpolate by time!");
           }
           // interpolate even if time is running backwards.
-          npts = std::abs(timespan.value()) / max_time_step;
+          npts = std::abs(*timespan) / max_time_step;
         } else if (opt_dist != nullptr) {
           double distspan = radtomiles(gcdist(RAD(lat1),
                                               RAD(lon1),
@@ -122,7 +122,7 @@ void InterpolateFilter::process()
           wpt_new->description = QString();
           if (timespan.has_value()) {
             wpt_new->SetCreationTime(0, time1.toMSecsSinceEpoch() +
-                                     round(frac * timespan.value()));
+                                     round(frac * *timespan));
           } else {
             wpt_new->creation_time = gpsbabel::DateTime();
           }
@@ -132,7 +132,7 @@ void InterpolateFilter::process()
                    &wpt_new->latitude,
                    &wpt_new->longitude);
           if (altspan.has_value()) {
-            wpt_new->altitude = altitude1 + (frac * altspan.value());
+            wpt_new->altitude = altitude1 + (frac * *altspan);
           } else {
             wpt_new->altitude = unknown_alt;
           }
index c3ba39add53e946661f298b9921a1c1e8c21d867..e2590228e66dd78b22faa989db89be21939404b0 100644 (file)
 #ifndef INTERPOLATE_H_INCLUDED_
 #define INTERPOLATE_H_INCLUDED_
 
+#include <optional>             // for optional
+
 #include <QtCore/QVector>       // for QVector
 #include <QtCore/QtGlobal>      // for qint64
 
 #include "defs.h"               // for ARG_NOMINMAX, arglist_t, ARGTYPE_BEGIN_EXCL, ARG...
 #include "filter.h"             // for Filter
-#include "src/core/optional.h"  // for optional
 
 #if FILTERS_ENABLED
 
diff --git a/kml.cc b/kml.cc
index 10286989350693ed8ec7799bed032d6484568c71..07435c090692cde38813b7db9d61aa0da87a2bf4 100644 (file)
--- a/kml.cc
+++ b/kml.cc
@@ -25,6 +25,7 @@
 #include <cstdio>                       // for sscanf, printf
 #include <cstdlib>                      // for atoi, atol, atof
 #include <cstring>                      // for strcmp
+#include <optional>                     // for optional
 #include <tuple>                        // for tuple, make_tuple, tie
 
 #include <QtCore/QByteArray>            // for QByteArray
@@ -49,7 +50,6 @@
 #include "src/core/datetime.h"          // for DateTime
 #include "src/core/file.h"              // for File
 #include "src/core/logging.h"           // for Warning, Fatal
-#include "src/core/optional.h"          // for optional
 #include "src/core/xmlstreamwriter.h"   // for XmlStreamWriter
 #include "src/core/xmltag.h"            // for xml_findfirst, xml_tag, fs_xml, xml_attribute, xml_findnext
 #include "units.h"                      // for fmt_setunits, fmt_speed, fmt_altitude, fmt_distance, units_aviation, units_metric, units_nautical, units_statute
index ff602d0ae4fe7f02c529fc46bec6d476694f7fdb..247f23a7f47c2775d4290218330415860839f20d 100644 (file)
@@ -118,33 +118,6 @@ extern WaypointList* global_waypoint_list;
 
 #define MYNAME "Lowrance USR"
 
-// Until c++17 we have to define odr-used constexpr static data members at namespace scope.
-#if __cplusplus < 201703L
-constexpr int LowranceusrFormat::DEF_ICON;
-constexpr int LowranceusrFormat::X_1_ICON;
-constexpr const char* LowranceusrFormat::DISABLED_CACHE_TXT;
-// MSVC 2015 will error with C2373 if the array length isn't explicitly included.
-#if !defined(_MSC_VER) || (_MSC_VER >= 1910) /* !MSVC or MSVC 2017 or newer */
-constexpr LowranceusrFormat::lowranceusr_icon_mapping_t LowranceusrFormat::lowranceusr_icon_value_table[];
-#else
-constexpr LowranceusrFormat::lowranceusr_icon_mapping_t LowranceusrFormat::lowranceusr_icon_value_table[134];
-#endif
-constexpr int LowranceusrFormat::DEF_USR4_ICON;
-constexpr int LowranceusrFormat::DEF_USR4_COLOR;
-// MSVC 2015 will error with C2373 if the array length isn't explicitly included.
-#if !defined(_MSC_VER) || (_MSC_VER >= 1910) /* !MSVC or MSVC 2017 or newer */
-constexpr LowranceusrFormat::lowranceusr4_icon_mapping_t LowranceusrFormat::lowranceusr4_icon_value_table[];
-#else
-constexpr LowranceusrFormat::lowranceusr4_icon_mapping_t LowranceusrFormat::lowranceusr4_icon_value_table[22];
-#endif
-constexpr int LowranceusrFormat::MAXUSRSTRINGSIZE;
-constexpr double LowranceusrFormat::SEMIMINOR;
-constexpr double LowranceusrFormat::DEGREESTORADIANS;
-constexpr int LowranceusrFormat::MAX_TRAIL_POINTS;
-constexpr double LowranceusrFormat::UNKNOWN_USR_ALTITUDE;
-constexpr time_t LowranceusrFormat::base_time_secs;
-#endif
-
 /* below couple of functions mostly borrowed from raymarine.c */
 
 /* make waypoint shortnames unique */
index 6ac4e66d0e62fde47ba6718a86dc248231f607ef..a4bf4621e9fa169c69232fb15ada39ef8c9311be 100644 (file)
@@ -193,12 +193,7 @@ private:
   static constexpr int X_1_ICON = 10003;
   static constexpr const char* DISABLED_CACHE_TXT = "Disabled Cache";
 
-// MSVC 2015 will error with C2373 if the array length isn't explicitly included.
-#if !defined(_MSC_VER) || (_MSC_VER >= 1910) /* !MSVC or MSVC 2017 or newer */
   static constexpr lowranceusr_icon_mapping_t lowranceusr_icon_value_table[] = {
-#else
-  static constexpr lowranceusr_icon_mapping_t lowranceusr_icon_value_table[134] = {
-#endif
 
     /* Taken from iFinder 1.8 */
 
@@ -361,12 +356,7 @@ private:
   static constexpr int DEF_USR4_ICON = 2;
   static constexpr int DEF_USR4_COLOR = 0;
 
-// MSVC 2015 will error with C2373 if the array length isn't explicitly included.
-#if !defined(_MSC_VER) || (_MSC_VER >= 1910) /* !MSVC or MSVC 2017 or newer */
   static constexpr lowranceusr4_icon_mapping_t lowranceusr4_icon_value_table[] = {
-#else
-  static constexpr lowranceusr4_icon_mapping_t lowranceusr4_icon_value_table[22] = {
-#endif
 
     /*  USR     GPX Symbol                COLOR1     COLOR2     COLOR3    COLOR4     COLOR5    COLOR6      COLOR7         HOOK2 Displays */
 
diff --git a/main.cc b/main.cc
index 5dd24e5c71679ca60cd51d17194c3307ba91275e..6de61fc2fdee46ab53820f32b4c0896a7e5e3dea 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -645,11 +645,17 @@ main(int argc, char* argv[])
   int rc = 0;
   const char* prog_name = argv[0]; /* may not match QCoreApplication::arguments().at(0)! */
 
-// MIN_QT_VERSION in configure.ac should correspond to the QT_VERSION_CHECK arguments in main.cc and gui/main.cc
-#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
+// MIN_QT_VERSION in GPSBabel.pro should correspond to the QT_VERSION_CHECK
+// arguments in main.cc and gui/main.cc and the version check in
+// CMakeLists.txt, gui/CMakeLists.txt.
+#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
 #error This version of Qt is not supported.
 #endif
 
+#if defined(_MSC_VER) && (_MSC_VER < 1910) /* MSVC 2015 or earlier */
+#error MSVC 2015 and earlier are not supported. Please use MSVC 2017 or MSVC 2019.
+#endif
+
 #ifdef DEBUG_LOCALE
   printf("Initial locale: %s\n",setlocale(LC_ALL, NULL));
 #endif
index 6374e908dd78c8145ea3eb6eaed9fcb50d5bca1b..24a31236d428a247b4a705931bd651c281998659 100644 (file)
@@ -2,7 +2,7 @@ QT -= gui
 
 CONFIG += console
 CONFIG -= app_bundle
-CONFIG += c++14
+CONFIG += c++17
 
 TEMPLATE = app
 
index 36470f4eeac44cfa42b5a7f370c70485bde70fb7..6beddea0585bf86a8420aeadb9a86e11aa94e5b9 100644 (file)
--- a/route.cc
+++ b/route.cc
@@ -21,6 +21,7 @@
 #include <cstddef>              // for nullptr_t
 #include <algorithm>            // for sort
 #include <iterator>
+#include <optional>             // for optional, operator>, operator<
 
 #include <QtCore/QDateTime>     // for QDateTime
 #include <QtCore/QList>         // for QList<>::iterator
@@ -31,7 +32,6 @@
 #include "grtcirc.h"            // for RAD, gcdist, heading_true_degrees, radtometers
 #include "session.h"            // for curr_session, session_t (ptr only)
 #include "src/core/datetime.h"  // for DateTime
-#include "src/core/optional.h"  // for optional, operator>, operator<
 
 
 RouteList* global_route_list;
index 9e92ddc0663c282a43e38eec0fbe436b42ad962e..20811648dd6f72310877771a8643705ace6fad26 100644 (file)
@@ -785,7 +785,7 @@ process_data_item(struct read_state* pst, const item_frame* pitem, int len)
 
   case 0xc:    /* POI item (same structure as full) */
     poi = 1;
-    /* fallthrough */
+    [[fallthrough]];
 
   case 0x2:    /* Multi HZ item */
     if (len < MULTI_HZ_ITEM_LEN) {
@@ -822,7 +822,7 @@ process_data_item(struct read_state* pst, const item_frame* pitem, int len)
 
   case 0x6:    /* POI item (same structure as full) */
     poi = 1;
-    /* fallthrough */
+    [[fallthrough]];
 
   case 0x4:    /* full item */
     if (len < FULL_ITEM_LEN) {
diff --git a/src/core/deprecated/optional.h b/src/core/deprecated/optional.h
new file mode 100644 (file)
index 0000000..df07b5b
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+    Copyright (C) 2018 Robert Lipe, robertlipe@gpsbabel.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ */
+
+// someday, when we require c++17,
+// the intent is that this can all go away by
+// changing:
+// 1. 'gpsbabel_optional::optional' to 'std::optional',
+// 2. 'include "optional.h"' becomes 'include <optional>'.
+
+#ifndef GPSBABEL_OPTIONAL_H_INCLUDED_
+#define GPSBABEL_OPTIONAL_H_INCLUDED_
+
+#if __cplusplus >= 201703L
+#warning "using std::optional"
+#include <optional>
+#define gpsbabel_optional std
+#else
+#include <cassert>
+namespace gpsbabel_optional
+{
+template<typename T>
+class optional
+{
+private:
+  bool null{true};
+  T v{};
+
+public:
+  constexpr optional() noexcept = default;
+  explicit optional(T n) : null{false}, v{n} {}
+
+  // There is a known mismatch with std::optional.
+  // o = {}; should act like reset() so o.has_value() returns false.
+  //         instead o.has_value() returns true and o.value() returns 0.
+  optional& operator=(const T& rhs)
+  {
+    null = false;
+    v = rhs;
+    return *this;
+  }
+
+  // if constexpr will conflict with constexpr non-const version in c++11, ok in c++14.
+  // but MSVC2015 with the c++14 standard can't handle it.  MSVC2017 is ok.
+  // intentionally does not check to see if a value is contained, use value() for that.
+  const T& operator*() const&
+  {
+    return v;
+  }
+
+  // if constexpr will conflict with constexpr const version in c++11, ok in c++14.
+  // but MSVC2015 with the c++14 standard can't handle it.  MSVC2017 is ok.
+  // intentionally does not check to see if a value is contained, use value() for that.
+  T& operator*()&
+  {
+    return v;
+  }
+
+  constexpr explicit operator bool() const noexcept
+  {
+    return !null;
+  }
+
+  constexpr bool has_value() const noexcept
+  {
+    return !null;
+  }
+
+  // if constexpr will conflict with constexpr const version in c++11, ok in c++14.
+  // but MSVC2015 with the c++14 standard can't handle it.  MSVC2017 is ok.
+  // if constexpr cannot use assert.
+  T& value() &
+  {
+    assert(!null);
+    return v;
+  }
+
+  // if constexpr will conflict with constexpr non-const version in c++11, ok in c++14.
+  // but MSVC2015 with the c++14 standard can't handle it.  MSVC2017 is ok.
+  // if constexpr cannot use assert.
+  const T& value() const&
+  {
+    assert(!null);
+    return v;
+  }
+
+  void reset() noexcept
+  {
+    null = true;
+  }
+};
+
+template< class T, class U >
+constexpr bool operator==(const optional<T>& lhs, const optional<U>& rhs)
+{
+  if (bool(lhs) != bool(rhs)) {
+    return false;
+  }
+  if (bool(lhs) == false) {
+    return true;
+  }
+  return *lhs == *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator!=(const optional<T>& lhs, const optional<U>& rhs)
+{
+  if (bool(lhs) != bool(rhs)) {
+    return true;
+  }
+  if (bool(lhs) == false) {
+    return false;
+  }
+  return *lhs != *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator<(const optional<T>& lhs, const optional<U>& rhs)
+{
+  if (!rhs) {
+    return false;
+  }
+  if (!lhs) {
+    return true;
+  }
+  return *lhs < *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator>(const optional<T>& lhs, const optional<U>& rhs)
+{
+  if (!lhs) {
+    return false;
+  }
+  if (!rhs) {
+    return true;
+  }
+  return *lhs > *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator<=(const optional<T>& lhs, const optional<U>& rhs)
+{
+  if (!lhs) {
+    return true;
+  }
+  if (!rhs) {
+    return false;
+  }
+  return *lhs <= *rhs;
+}
+
+template< class T, class U >
+constexpr bool operator>=(const optional<T>& lhs, const optional<U>& rhs)
+{
+  if (!rhs) {
+    return true;
+  }
+  if (!lhs) {
+    return false;
+  }
+  return *lhs >= *rhs;
+}
+
+
+template< class T, class U >
+constexpr bool operator==(const optional<T>& opt, const U& value)
+{
+  return bool(opt) ? (*opt == value) : false;
+}
+
+template< class T, class U >
+constexpr bool operator==(const T& value, const optional<U>& opt)
+{
+  return bool(opt) ? (value == *opt) : false;
+}
+
+template< class T, class U >
+constexpr bool operator!=(const optional<T>& opt, const U& value)
+{
+  return bool(opt) ? (*opt != value) : true;
+}
+
+template< class T, class U >
+constexpr bool operator!=(const T& value, const optional<U>& opt)
+{
+  return bool(opt) ? (value != *opt) : true;
+}
+
+template< class T, class U >
+constexpr bool operator<(const optional<T>& opt, const U& value)
+{
+  return bool(opt) ? (*opt < value) : true;
+}
+
+template< class T, class U >
+constexpr bool operator<(const T& value, const optional<U>& opt)
+{
+  return bool(opt) ? (value < *opt) : false;
+}
+
+template< class T, class U >
+constexpr bool operator<=(const optional<T>& opt, const U& value)
+{
+  return bool(opt) ? *opt <= value : true;
+}
+
+template< class T, class U >
+constexpr bool operator<=(const T& value, const optional<U>& opt)
+{
+  return bool(opt) ? value <= *opt : false;
+}
+
+template< class T, class U >
+constexpr bool operator>(const optional<T>& opt, const U& value)
+{
+  return bool(opt) ? (*opt > value) : false;
+}
+
+template< class T, class U >
+constexpr bool operator>(const T& value, const optional<U>& opt)
+{
+  return bool(opt) ? (value > *opt) : true;
+}
+
+template< class T, class U >
+constexpr bool operator>=(const optional<T>& opt, const U& value)
+{
+  return bool(opt) ? (*opt >= value) : false;
+}
+
+template< class T, class U >
+constexpr bool operator>=(const T& value, const optional<U>& opt)
+{
+  return bool(opt) ? (value >= *opt) : true;
+}
+
+} // namespace
+#endif
+
+#endif // GPSBABEL_OPTIONAL_H_INCLUDED_
diff --git a/src/core/optional.h b/src/core/optional.h
deleted file mode 100644 (file)
index df07b5b..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
-    Copyright (C) 2018 Robert Lipe, robertlipe@gpsbabel.org
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
- */
-
-// someday, when we require c++17,
-// the intent is that this can all go away by
-// changing:
-// 1. 'gpsbabel_optional::optional' to 'std::optional',
-// 2. 'include "optional.h"' becomes 'include <optional>'.
-
-#ifndef GPSBABEL_OPTIONAL_H_INCLUDED_
-#define GPSBABEL_OPTIONAL_H_INCLUDED_
-
-#if __cplusplus >= 201703L
-#warning "using std::optional"
-#include <optional>
-#define gpsbabel_optional std
-#else
-#include <cassert>
-namespace gpsbabel_optional
-{
-template<typename T>
-class optional
-{
-private:
-  bool null{true};
-  T v{};
-
-public:
-  constexpr optional() noexcept = default;
-  explicit optional(T n) : null{false}, v{n} {}
-
-  // There is a known mismatch with std::optional.
-  // o = {}; should act like reset() so o.has_value() returns false.
-  //         instead o.has_value() returns true and o.value() returns 0.
-  optional& operator=(const T& rhs)
-  {
-    null = false;
-    v = rhs;
-    return *this;
-  }
-
-  // if constexpr will conflict with constexpr non-const version in c++11, ok in c++14.
-  // but MSVC2015 with the c++14 standard can't handle it.  MSVC2017 is ok.
-  // intentionally does not check to see if a value is contained, use value() for that.
-  const T& operator*() const&
-  {
-    return v;
-  }
-
-  // if constexpr will conflict with constexpr const version in c++11, ok in c++14.
-  // but MSVC2015 with the c++14 standard can't handle it.  MSVC2017 is ok.
-  // intentionally does not check to see if a value is contained, use value() for that.
-  T& operator*()&
-  {
-    return v;
-  }
-
-  constexpr explicit operator bool() const noexcept
-  {
-    return !null;
-  }
-
-  constexpr bool has_value() const noexcept
-  {
-    return !null;
-  }
-
-  // if constexpr will conflict with constexpr const version in c++11, ok in c++14.
-  // but MSVC2015 with the c++14 standard can't handle it.  MSVC2017 is ok.
-  // if constexpr cannot use assert.
-  T& value() &
-  {
-    assert(!null);
-    return v;
-  }
-
-  // if constexpr will conflict with constexpr non-const version in c++11, ok in c++14.
-  // but MSVC2015 with the c++14 standard can't handle it.  MSVC2017 is ok.
-  // if constexpr cannot use assert.
-  const T& value() const&
-  {
-    assert(!null);
-    return v;
-  }
-
-  void reset() noexcept
-  {
-    null = true;
-  }
-};
-
-template< class T, class U >
-constexpr bool operator==(const optional<T>& lhs, const optional<U>& rhs)
-{
-  if (bool(lhs) != bool(rhs)) {
-    return false;
-  }
-  if (bool(lhs) == false) {
-    return true;
-  }
-  return *lhs == *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator!=(const optional<T>& lhs, const optional<U>& rhs)
-{
-  if (bool(lhs) != bool(rhs)) {
-    return true;
-  }
-  if (bool(lhs) == false) {
-    return false;
-  }
-  return *lhs != *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator<(const optional<T>& lhs, const optional<U>& rhs)
-{
-  if (!rhs) {
-    return false;
-  }
-  if (!lhs) {
-    return true;
-  }
-  return *lhs < *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator>(const optional<T>& lhs, const optional<U>& rhs)
-{
-  if (!lhs) {
-    return false;
-  }
-  if (!rhs) {
-    return true;
-  }
-  return *lhs > *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator<=(const optional<T>& lhs, const optional<U>& rhs)
-{
-  if (!lhs) {
-    return true;
-  }
-  if (!rhs) {
-    return false;
-  }
-  return *lhs <= *rhs;
-}
-
-template< class T, class U >
-constexpr bool operator>=(const optional<T>& lhs, const optional<U>& rhs)
-{
-  if (!rhs) {
-    return true;
-  }
-  if (!lhs) {
-    return false;
-  }
-  return *lhs >= *rhs;
-}
-
-
-template< class T, class U >
-constexpr bool operator==(const optional<T>& opt, const U& value)
-{
-  return bool(opt) ? (*opt == value) : false;
-}
-
-template< class T, class U >
-constexpr bool operator==(const T& value, const optional<U>& opt)
-{
-  return bool(opt) ? (value == *opt) : false;
-}
-
-template< class T, class U >
-constexpr bool operator!=(const optional<T>& opt, const U& value)
-{
-  return bool(opt) ? (*opt != value) : true;
-}
-
-template< class T, class U >
-constexpr bool operator!=(const T& value, const optional<U>& opt)
-{
-  return bool(opt) ? (value != *opt) : true;
-}
-
-template< class T, class U >
-constexpr bool operator<(const optional<T>& opt, const U& value)
-{
-  return bool(opt) ? (*opt < value) : true;
-}
-
-template< class T, class U >
-constexpr bool operator<(const T& value, const optional<U>& opt)
-{
-  return bool(opt) ? (value < *opt) : false;
-}
-
-template< class T, class U >
-constexpr bool operator<=(const optional<T>& opt, const U& value)
-{
-  return bool(opt) ? *opt <= value : true;
-}
-
-template< class T, class U >
-constexpr bool operator<=(const T& value, const optional<U>& opt)
-{
-  return bool(opt) ? value <= *opt : false;
-}
-
-template< class T, class U >
-constexpr bool operator>(const optional<T>& opt, const U& value)
-{
-  return bool(opt) ? (*opt > value) : false;
-}
-
-template< class T, class U >
-constexpr bool operator>(const T& value, const optional<U>& opt)
-{
-  return bool(opt) ? (value > *opt) : true;
-}
-
-template< class T, class U >
-constexpr bool operator>=(const optional<T>& opt, const U& value)
-{
-  return bool(opt) ? (*opt >= value) : false;
-}
-
-template< class T, class U >
-constexpr bool operator>=(const T& value, const optional<U>& opt)
-{
-  return bool(opt) ? (value >= *opt) : true;
-}
-
-} // namespace
-#endif
-
-#endif // GPSBABEL_OPTIONAL_H_INCLUDED_
diff --git a/util.cc b/util.cc
index 96390bdaed6f73dac5cd4a28133bae9a4a468ca5..387b0057e77b16140e6b68915aa716499e4fa574 100644 (file)
--- a/util.cc
+++ b/util.cc
@@ -501,7 +501,7 @@ str_match(const char* str, const char* match)
         return 0;  /* incomplete escape sequence */
       }
     /* pass-through next character */
-    /* fallthrough */
+    [[fallthrough]];
 
     default:
       if (*m != *s) {
@@ -632,7 +632,7 @@ le_read64(void* dest, const void* src)
   char* cdest = (char*) dest;
   const char* csrc = (const char*) src;
 
-  if (i_am_little_endian) {
+  if constexpr (i_am_little_endian) {
     memcpy(dest, src, 8);
   } else {
     int i;
diff --git a/xcsv.cc b/xcsv.cc
index 771fc16d94ca3d045c2213b4c3475ca59d30f68b..98aa71ca941dfd60e82ae54c9526d251985451cb 100644 (file)
--- a/xcsv.cc
+++ b/xcsv.cc
@@ -30,6 +30,7 @@
 #include <cstdlib>                    // for atof, atoi, strtod
 #include <cstring>                    // for strlen, strncmp, strcmp, memset
 #include <ctime>                      // for gmtime, localtime, time_t, mktime, strftime
+#include <optional>                   // for optional
 
 #include <QtCore/QByteArray>          // for QByteArray
 #include <QtCore/QChar>               // for QChar
@@ -56,7 +57,6 @@
 #include "session.h"                  // for session_t
 #include "src/core/datetime.h"        // for DateTime
 #include "src/core/logging.h"         // for FatalMsg
-#include "src/core/optional.h"        // for optional
 #include "src/core/textstream.h"      // for TextStream
 #include "strptime.h"                 // for strptime
 #include "xcsv.h"
@@ -879,10 +879,10 @@ XcsvFormat::read()
 
       // If XT_LAT_DIR(XT_LON_DIR) was an input field, and the latitude(longitude) is positive,
       // assume the latitude(longitude) was the absolute value and take the sign from XT_LAT_DIR(XT_LON_DIR).
-      if (parse_data.lat_dir_positive.has_value() && !parse_data.lat_dir_positive.value() && (wpt_tmp->latitude > 0.0)) {
+      if (parse_data.lat_dir_positive.has_value() && !(*parse_data.lat_dir_positive) && (wpt_tmp->latitude > 0.0)) {
         wpt_tmp->latitude = -wpt_tmp->latitude;
       }
-      if (parse_data.lon_dir_positive.has_value() && !parse_data.lon_dir_positive.value() && (wpt_tmp->longitude > 0.0)) {
+      if (parse_data.lon_dir_positive.has_value() && !(*parse_data.lon_dir_positive) && (wpt_tmp->longitude > 0.0)) {
         wpt_tmp->longitude = -wpt_tmp->longitude;
       }
 
diff --git a/xcsv.h b/xcsv.h
index f4c6ddc3f58b61b37b0cc169ca1bcb74b0723d9a..2b43010ae3954512e728547aa35d7e6b4726da5b 100644 (file)
--- a/xcsv.h
+++ b/xcsv.h
@@ -22,6 +22,7 @@
 #define XCSV_H_INCLUDED_
 
 #include <ctime>
+#include <optional>               // for optional
 #include <utility>                // for move
 
 #include <QtCore/QByteArray>      // for QByteArray
@@ -36,7 +37,6 @@
 #include "format.h"
 #include "garmin_fs.h"
 #include "src/core/datetime.h"    // for DateTime
-#include "src/core/optional.h"    // for optional
 #include "src/core/textstream.h"  // for TextStream
 
 #if CSVFMTS_ENABLED
@@ -235,10 +235,10 @@ public:
   gpsdata_type datatype{unknown_gpsdata};
 
   /* SHORTLEN from style file */
-  gpsbabel_optional::optional<int> shortlen;
+  std::optional<int> shortlen;
 
   /* SHORTWHITE from style file */
-  gpsbabel_optional::optional<int> whitespace_ok;
+  std::optional<int> whitespace_ok;
 
 private:
   /* Types */
@@ -346,8 +346,8 @@ private:
     double utm_zone{0};
     char utm_zonec{'N'};
     UrlLink* link_{nullptr};
-    gpsbabel_optional::optional<bool> lat_dir_positive;
-    gpsbabel_optional::optional<bool> lon_dir_positive;
+    std::optional<bool> lat_dir_positive;
+    std::optional<bool> lon_dir_positive;
   };
 
   /* Constants */